package com.sinosoft.msf.base.supplier.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.sinosoft.msf.base.supplier.dao.base.*;
import com.sinosoft.msf.base.supplier.expection.BizException;
import com.sinosoft.msf.base.supplier.pojo.OptVo;
import com.sinosoft.msf.base.supplier.pojo.ProjectInfoPojo;
import com.sinosoft.msf.base.supplier.pojo.email.SendVo;
import com.sinosoft.msf.base.supplier.pojo.entity.SCompanyContract;
import com.sinosoft.msf.base.supplier.pojo.entity.SCompanyInfo;
import com.sinosoft.msf.base.supplier.pojo.entity.SProjectCompany;
import com.sinosoft.msf.base.supplier.pojo.entity.SProjectInfo;
import com.sinosoft.msf.base.supplier.props.ComStateEnum;
import com.sinosoft.msf.base.supplier.props.ProjectStateEnum;
import com.sinosoft.msf.base.supplier.props.SupProps;
import com.sinosoft.msf.base.supplier.props.UserRoleEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SupSendService {
    @Autowired
    SupProps supProps;
    @Autowired
    SCompanyContractMapper sCompanyContractMapper;
    @Autowired
    CommonInterService interService;
    @Autowired
    CompanyUserRoleService userRoleService;
    @Autowired
    SProjectCompanyMapper projectCompanyMapper;
    @Autowired
    SContractMapper sContractMapper;
    @Autowired
    StringRedisTemplate redisUtil;
    @Autowired
    SProjectInfoMapper sProjectInfoMapper;
    @Autowired
    SCompanyInfoMapper sCompanyInfoMapper;
    @Async
    public void sendEmail(String title, List<String> param, List<String> receiver, String temNo) {
        log.info("标题：{},内容：{},接收人::{}", title, JSON.toJSONString(param), JSON.toJSONString(receiver));
//        List<String> names = new ArrayList<>();
//        names.add("费控");
        SendVo.EmailInfoDTO infoDTO = new SendVo.EmailInfoDTO();
        infoDTO.setTitle(title);
        SendVo vo = new SendVo();
        vo.setTemplate(temNo);
        vo.setSecretKey(supProps.getSendSecretKey());
        vo.setContents(param);
        vo.setEmailInfo(infoDTO);
        vo.setToUser(receiver);
//        RestEntity restEntity = baseEmailFeign.msgPush(vo);
        log.info("发送邮件通知完成：{},返回值：{}", JSON.toJSONString(vo),JSON.toJSONString("restEntity"));

    }
    /**
     * 当日未处理“供应商管理助手”审核任务提醒：
     * 您收到X条审核任务尚未处理，请及时处理。
     * 请点击此处进行查看>（PC端链接）
     * 或通过企业微信-工作台-供应商助手进行查看
     * （如已处理请忽略）
     * @param type
     * @param optVo 登录用户信息
     */
    public void sendWechat(String type, OptVo optVo) {
        if (TransactionSynchronizationManager.isActualTransactionActive()){
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    // 事务提交后执行回调
                    ThreadUtil.execute(()->sendWechatAction(type,optVo));
                }
            });
        }else{
            ThreadUtil.execute(()->sendWechatAction(type,optVo));
        }

    }
    public int queryComCountByState(String state) {
        SCompanyInfo info = new SCompanyInfo();
        info.setState(state);
        return sCompanyInfoMapper.selectCount(info);
    }
    public int queryProjectCountByState(String state) {
        SProjectInfo info = new ProjectInfoPojo();
        info.setStatus(state);
        return sProjectInfoMapper.selectCount(info);
    }
    @Async
    public void sendWechatAction(String type, OptVo optVo) {
        List<String> users = new ArrayList<>();
        int count = 0;
        String comInputUrl = supProps.getComInputUrl();
        if (comInputUrl.contains("#")) {
            comInputUrl = comInputUrl.substring(0, comInputUrl.indexOf("#"));
        }
        if (ComStateEnum.WAL.name().equals(type)) {
            log.info("发送法务：{}", type);
            users = userRoleService.queryIdByRole(UserRoleEnum.legal);
            count = queryComCountByState(ComStateEnum.WAL.name());
        } else if (ComStateEnum.WAL2.name().equals(type)) {
            log.info("发送管理员：{}", type);
            users = userRoleService.queryIdByRole(UserRoleEnum.legal2);
            count = queryComCountByState(ComStateEnum.WAL2.name());
        } else if (ComStateEnum.WAA.name().equals(type)) {
            log.info("发送管理员：{}", type);
            users = userRoleService.queryIdByRole(UserRoleEnum.admin);
            count = queryComCountByState(ComStateEnum.WAA.name());
        }else if (ProjectStateEnum.lgd.name().equals(type)) {
            log.info("发送法务：{}", type);
            users = userRoleService.queryIdByRole(UserRoleEnum.legal);
            count = queryProjectCountByState(ProjectStateEnum.lgd.name());
        }else if (ProjectStateEnum.lgd2.name().equals(type)) {
            log.info("发送法务：{}", type);
            users = userRoleService.queryIdByRole(UserRoleEnum.legal2);
            count = queryProjectCountByState(ProjectStateEnum.lgd2.name());
        }
        if (CollUtil.isNotEmpty(users) && count>0) {
            List<String> names = new ArrayList<>();
            names.add(count+"");
            names.add(comInputUrl);
            SendVo vo = new SendVo();
            vo.setTemplate(supProps.getSendWechatTmpNo());
            vo.setSecretKey(supProps.getSendSecretKey());
            vo.setContents(names);
            vo.setToUser(users);
//            RestEntity restEntity = baseEmailFeign.msgPush(vo);
            log.info("发送企微通知完成：{},返回值：{}", JSON.toJSONString(vo),JSON.toJSONString("restEntity"));

        } else {
            log.info("人员信息不为空:{}，或是数量为空:{}，未发送",CollUtil.isNotEmpty(users),count);
        }

    }

    /**
     * 标题：大家人寿业务采购系统
     * 正文：您好，贵司未通过入库审核，请登录系统查看审核结果，修改链接（录入链接）。
     *
     * @param sCompanyInfo
     */
    @Async
    public void notifyContract(SCompanyInfo sCompanyInfo) {
        String url = interService.fetchComInputUrl(sCompanyInfo.getId());
        String title = "大家人寿业务采购系统";
        List<String> param = new ArrayList<>();
        param.add(url);
        Example exp = new Example(SCompanyContract.class, true, true);
        exp.createCriteria().andEqualTo("companyId", sCompanyInfo.getId()).andEqualTo("deleted","n");
        List<SCompanyContract> contracts = sCompanyContractMapper.selectByExample(exp);
        if (CollUtil.isNotEmpty(contracts)) {
            List<String> collect = contracts.stream().map(SCompanyContract::getContactEmail).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
            sendEmail(title, param, collect, supProps.getSendNoPassTmpNo());
        }

    }

    /**
     * 标题：大家人寿业务采购平台信息修改邀请链接
     * 正文：请确认为注册授权联系人本人进行操作，链接（{}）。
     */
    @Async
    public void notifyContractModify(SCompanyInfo sCompanyInfo) {
        String url = interService.fetchComInputUrl(sCompanyInfo.getId());
        String title = "大家人寿业务采购平台信息修改邀请链接";
        List<String> param = new ArrayList<>();
        param.add(url);
        Example exp = new Example(SCompanyContract.class, true, true);
        exp.createCriteria().andEqualTo("companyId", sCompanyInfo.getId()).andEqualTo("deleted","n");
        List<SCompanyContract> contracts = sCompanyContractMapper.selectByExample(exp);
        if (CollUtil.isNotEmpty(contracts)) {
            List<String> collect = contracts.stream().map(SCompanyContract::getContactEmail).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
            sendEmail(title, param, collect, supProps.getSendNoPassTmpNo());
        }
    }

    /**
     * 标题：大家人寿业务采购邀请
     * 正文：您好，诚邀贵公司参与我司{}采购项目，请尽快登录我司平台查看项目资料，下载报价清单，上传报价单链接（{}）。
     */
    @Async
    public void notifyUpload(SProjectInfo sProjectInfo) {
        String title = "大家人寿业务采购邀请";
        List<String> param = new ArrayList<>();
        param.add(sProjectInfo.getProjectName());
        param.add(supProps.getPriceInputUrl() + sProjectInfo.getId());

        Example exp = new Example(SProjectCompany.class, true, true);
        exp.createCriteria().andEqualTo("projectId", sProjectInfo.getId()).andEqualTo("deleted","n");
        List<SProjectCompany> contracts = projectCompanyMapper.selectByExample(exp);
        if (CollUtil.isNotEmpty(contracts)) {
            List<String> comIds = contracts.stream().map(SProjectCompany::getCompanyId).collect(Collectors.toList());
            List<SCompanyContract> contractList = sContractMapper.queryContractByCIds(comIds);
            if (CollUtil.isNotEmpty(contractList)) {
                List<String> collect = contractList.stream().map(SCompanyContract::getContactEmail).collect(Collectors.toList());
                sendEmail(title, param, collect, supProps.getSendUploadTmpNo());
            }
        }

    }
    public void sendSms(String phone,String code,String comName) {
        if ("y".equalsIgnoreCase(supProps.getSendTestSms())) {
            code = "111111";
            log.info("发送短信,接收人：{},使用测试验证码：{}",phone,code);
        }
        log.info("发送短信,接收人：{},验证码：{}",phone,code);

        List<String> names = new ArrayList<>();
        names.add(code);
        SendVo vo = new SendVo();
        vo.setTemplate(supProps.getSendSmsTmpNo());
        vo.setSecretKey(supProps.getSendSecretKey());
        vo.setContents(names);
        vo.setToUser(Arrays.asList(phone));
//        RestEntity restEntity = baseEmailFeign.msgPush(vo);
        log.info("发送短信通知完成：{},返回值：{}", JSON.toJSONString(vo),JSON.toJSONString("restEntity"));
        String key = smsCacheKey(phone,comName);
        redisUtil.opsForValue().set(key, code,60*5);
    }
    public boolean valiPhoneCode(String phone,String code,String comName) {
        String key = smsCacheKey(phone,comName);
        String v = (String) redisUtil.opsForValue().get(key);
        if (v == null) {
            throw new BizException("验证码已过期，请重新获取");
        }
        log.info("发送短信,接收人：{},输入验证码：{},正确验证码：{}",phone,code,v);
        boolean eq = v.equals(code);
        if (eq) {
            redisUtil.delete(key);
        }else{
            throw new BizException("验证码错误");
        }
        return eq;
    }

    public String smsCacheKey(String... param) {
        String collect = Arrays.stream(param).collect(Collectors.joining("="));
        String key =  SecureUtil.md5(collect);
        return "sup:valiinfo:"+key;
    }
}
